package com.cyys.common.em;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;


/**
 * 
 * @author LC
 *
 * @param <E>
 */
public class UniversalHandler<E extends BaseEnum<?, ?>> extends BaseTypeHandler<E> {  
	 private Class<E> type;  
	    private E [] enums;  
	      
	    /** 
	     * 设置配置文件设置的转换类以及枚举类内容，供其他方法更便捷高效的实现 
	     * @param type 配置文件中设置的转换类 
	     */  
	    public UniversalHandler(Class<E> type) {  
	        if (type == null)  
	            throw new IllegalArgumentException("Type argument cannot be null");  
	        this.type = type;  
	        this.enums = type.getEnumConstants();  
	        if (this.enums == null)  
	            throw new IllegalArgumentException(type.getSimpleName()  
	                    + " does not represent an enum type.");  
	    }  
	      
	    @Override  
	    public void setNonNullParameter(PreparedStatement ps, int i, E parameter,  
	            JdbcType jdbcType) throws SQLException {  
	        //BaseTypeHandler已经帮我们做了parameter的null判断  
	        ps.setObject(i,(String)parameter.getIndex(), jdbcType.TYPE_CODE);   
	    }  
	  
	    @Override  
	    public E getNullableResult(ResultSet rs, String columnName)  
	            throws SQLException {  
	        // 根据数据库存储类型决定获取类型，本例子中数据库中存放String类型  
	        String i = rs.getString(columnName);  
	        if (rs.wasNull()) {  
	            return null;  
	        } else {  
	            // 根据数据库中的value值，定位PersonType子类  
	            return locateEnumStatus(i);  
	        }  
	    }  
	  
	    @Override  
	    public E getNullableResult(ResultSet rs, int columnIndex)  
	            throws SQLException {  
	        // 根据数据库存储类型决定获取类型，本例子中数据库中存放String类型  
	        String i = rs.getString(columnIndex);  
	        if (rs.wasNull()) {  
	            return null;  
	        } else {  
	            // 根据数据库中的value值，定位PersonType子类  
	            return locateEnumStatus(i);  
	        }  
	    }  
	  
	    @Override  
	    public E getNullableResult(CallableStatement cs, int columnIndex)  
	            throws SQLException {
	        // 根据数据库存储类型决定获取类型，本例子中数据库中存放String类型  
	        String i = cs.getString(columnIndex);
	        if (cs.wasNull()) {
	            return null;
	        } else {
	            // 根据数据库中的value值，定位PersonType子类  
	            return locateEnumStatus(i);
	        }
	    }
	  
	     /** 
	     * 枚举类型转换，由于构造函数获取了枚举的子类enums，让遍历更加高效快捷 
	     * @param index 数据库中存储的自定义value属性 
	     * @return index对应的枚举类 
	     */  
	    private E locateEnumStatus(String index) {  
	        for(E e : enums) {
	            if(e.getIndex().toString().equals(index)) {
	                return e;
	            }
	        }
	        throw new IllegalArgumentException("未知的枚举类型：" + index + ",请核对" + type.getSimpleName());
	    } 

}
